unit uDZHash;

interface

uses
  uDZSysUtils;

function RSHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
function JSHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
function PJWHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
function ELFHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
function BKDRHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
function SDBMHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
function DJBHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
function APHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;

implementation

{.$region 'hash routines'}

function RSHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
var
  a, b, hash: Cardinal;
  i: Cardinal;
begin
  b  := 378551;
  a := 63689;
  hash := 0;
  for i := 0 to len - 1 do
  begin
    hash := hash * a + Byte(CASE_CHAR_TABLE[_case][buf[i]]);
    a := a * b;
  end;
	Result := hash and $7fffffff;
end;

function JSHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
var
  hash: Cardinal;
  i: Cardinal;
begin
  hash := 1315423911;
  for i := 0 to len - 1 do
    hash := hash xor
     ((hash shl 5)  +
        Byte(CASE_CHAR_TABLE[_case][buf[i]])  +
       (hash shr 2));
	Result := hash and $7fffffff;
end;

 {  P. J. Weinberger Hash Function  }
function PJWHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
const
  BitsInUnignedInt = SizeOf(Cardinal)  * 8;
  ThreeQuarters =(BitsInUnignedInt * 3) div 4;
  OneEighth = BitsInUnignedInt div 8;
  HighBits = $ffffffff shl(BitsInUnignedInt  -  OneEighth);
var
  hash, flag: Cardinal;
  i: Cardinal;
begin
  hash := 0;
  for i := 0 to len - 1 do
  begin
    hash :=(hash shl OneEighth) + Byte(CASE_CHAR_TABLE[_case][buf[i]]);
    flag := hash and HighBits;
    if(flag <> 0) then
      hash :=((hash xor(flag shr ThreeQuarters))
        and(not HighBits));
  end;
  Result := hash and $7fffffff;
end;

function ELFHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
var
  hash, x: Cardinal;
  i: Cardinal;
begin
	hash := 0;
  for i := 0 to len - 1 do
  begin
		hash :=(hash shl 4) + Byte(CASE_CHAR_TABLE[_case][buf[i]]);
    x := hash and $f0000000;
		if x <> 0 then
		begin
			hash := hash xor(x shr 24);
			hash := hash and not x;
		end; 
	end; 
  Result := hash and $7fffffff;
end;

function BKDRHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
var
  hash, seed: Cardinal;
  i: Cardinal;
begin
  seed := 131;  //  31 131 1313 13131 131313 etc..
  hash := 0;
  for i := 0 to len - 1 do
    hash := hash * seed + Byte(CASE_CHAR_TABLE[_case][buf[i]]);
	Result := hash and $7fffffff;
end;

function SDBMHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
var
  hash: Cardinal;
  i: Cardinal;
begin
  hash := 0;
  for i := 0 to len - 1 do
    hash := Byte(CASE_CHAR_TABLE[_case][buf[i]]) +(hash shl 6) +(hash shl 16) - hash;
	Result := hash and $7fffffff;
end;

function DJBHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
var
  hash: Cardinal;
  i: Cardinal;
begin
  hash := 5381;
  for i := 0 to len - 1 do
    hash := hash +(hash shl 5) + Byte(CASE_CHAR_TABLE[_case][buf[i]]);
  Result := hash and $7fffffff;
end;

function APHash(buf: PAnsiChar; len: Cardinal; _case: TCharCase): Cardinal;
var
  hash: Cardinal;
  i: Cardinal;
begin
  hash := 0;
  for i := 0 to len - 1 do
  begin
		if ((i and 1) = 0) then
			hash := hash xor(
       (hash shl 7) xor Byte(CASE_CHAR_TABLE[_case][buf[i]]) xor
       (hash shr 3))
      else
			  hash := hash xor(
          not((hash shl 11) xor Byte(CASE_CHAR_TABLE[_case][buf[i]]) xor
         (hash shr 5)));
  end;
  Result := hash and $7fffffff;
end;

{.$endregion}

end.
